package com.ttxs.generator.engine;

import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.fasterxml.jackson.core.type.TypeReference;
import com.ttxs.generator.remote.dto.AuthDTO;
import com.ttxs.generator.remote.dto.LoginDTO;
import com.ttxs.generator.remote.dto.MenuDTO;
import com.ttxs.generator.remote.dto.PlatformDTO;
import com.ttxs.generator.util.RestTemplateUtils;
import com.ttxs.generator.vo.FormBean;
import com.ttxs.generator.vo.Token;
import org.springframework.beans.BeanUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

import static com.ttxs.generator.remote.RemoteContants.DefaultValue;
import static com.ttxs.generator.remote.RemoteContants.Path;

public class AutoCreatePlatform {

    private String gatewayUrl;
    private FormBean formBean;
    private List<TableInfo> tableInfoList;

    public AutoCreatePlatform(FormBean formBean, List<TableInfo> tableInfoList) {
        this.formBean = formBean;
        this.tableInfoList = tableInfoList;
        this.gatewayUrl = formBean.getGatewayUrl();
    }

    public void autoCreate() {
        if (DefaultValue.ADMIN_PLATFORM_NAME.equals(formBean.getArtifactId())) {
            throw new RuntimeException("非法的项目名字");
        }
        if (DefaultValue.ADMIN_PLATFORM_NAME.equals(formBean.getPlatformName())) {
            throw new RuntimeException("非法的平台名字");
        }
        LoginDTO loginDTO = new LoginDTO(gatewayUrl + Path.LOGIN)
                .setPlatformName(DefaultValue.ADMIN_PLATFORM_NAME)
                .setUsername(formBean.getAdminUsername())
                .setPassword(formBean.getAdminPassword());
        // 登录管理平台
        Token token = RestTemplateUtils.postForm(loginDTO, Token.class);
        // 创建新平台
        PlatformDTO input = new PlatformDTO(gatewayUrl + Path.PLATFORM, token)
                // 判断是否为springcloud项目，设置对应的platformName
                .setPlatformName(formBean.isSpringCloud() ? formBean.getPlatformName() :formBean.getArtifactId())
                .setArtifactId(formBean.getArtifactId())
                .setPlatformNameZh("请输入平台中文名")
                .setDescription("请输入描述")
                .setStatus("0")
                .setSpringCloud(formBean.isSpringCloud());

        PlatformDTO returnValue = findPlatform(input);

        if (returnValue == null) {
            returnValue = RestTemplateUtils.post(input, PlatformDTO.class);
        }
        // 创建菜单并授权
        input.setPlatformId(returnValue.getPlatformId());
        input.setPlatformNameZh(returnValue.getPlatformNameZh());
        input.setStatus(returnValue.getStatus());
        autoCreateMenusAndAuthorize(input);
    }

    private PlatformDTO findPlatform(PlatformDTO input) {
        PlatformDTO cloned = new PlatformDTO();
        BeanUtils.copyProperties(input, cloned);
        cloned.setUrl(gatewayUrl + Path.PLATFORM_SEARCH + "?platformName={platformName}");
        List<PlatformDTO> list = RestTemplateUtils.get(cloned, new TypeReference<List<PlatformDTO>>() {
        },cloned.getPlatformName());
        return list.isEmpty() ? null : list.get(0);
    }

    private void autoCreateMenusAndAuthorize(PlatformDTO platformDTO) {
        // 登录新平台
        LoginDTO loginDTO = new LoginDTO(gatewayUrl + Path.LOGIN)
                .setPlatformName(platformDTO.getPlatformName())
                .setUsername(DefaultValue.ADMIN_USER_NAME)
                .setPassword(DefaultValue.DEFAULT_PASSWORD);
        Token token = RestTemplateUtils.postForm(loginDTO, Token.class);
        // 创建项目菜单
        createMenus(token, platformDTO);
        // 给admin用户授权所有菜单
        AuthDTO authDTO = new AuthDTO(gatewayUrl + Path.AUTH + "/list/all", token)
                .setRoleName(DefaultValue.ADMIN_ROLE_NAME);
        // 获取所有菜单
        List<MenuDTO> menuList = RestTemplateUtils.get(authDTO, new TypeReference<List<MenuDTO>>() {
        });
        // 选中所有菜单
        authDTO.setUrl(gatewayUrl + Path.AUTH);
        String checkedMenuIds = menuList.stream().map(menu -> String.valueOf(menu.getMenuId())).collect(Collectors.joining(","));
        authDTO.setCheckedMenuIds(checkedMenuIds);
        // 授权
        RestTemplateUtils.postForm(authDTO, Void.class);
    }

    private void createMenus(Token token, PlatformDTO platformDTO) {
        final String artifactId = platformDTO.getArtifactId();
        // 创建根菜单
        MenuDTO rootMenuDTO = new MenuDTO(gatewayUrl + Path.MENU, token);
        rootMenuDTO.setApiUrl(null)
                .setComponent(null)
                .setPlatformId(platformDTO.getPlatformId())
//                .setMenuName(platformDTO.getPlatformName())
                .setMenuName(artifactId)
                .setMenuType("M")
                .setParentId(0L)
                .setRestful(false)
                .setStatus("0")
                .setVisible("0");
        // 创建或找到根菜单
        MenuDTO rootMenu = createOrFind(rootMenuDTO);
        // 创建子菜单
        for (TableInfo tableInfo : tableInfoList) {
            MenuDTO childMenuDTO = new MenuDTO(gatewayUrl + Path.MENU, token);
            String comment = tableInfo.getComment();
            if(StringUtils.hasText(comment) && comment.endsWith("表")) {
                comment = comment.substring(0, comment.length() - 1) + "管理";
            } else {
                comment = tableInfo.getEntityName() + "管理";
            }
            if(platformDTO.isSpringCloud()) {
                childMenuDTO.setSpringCloud(true);
                childMenuDTO.setComponent(platformDTO.getPlatformName() + "/"
                        + artifactId
                        +"/" + tableInfo.getEntityPath() + "/index.vue");
                childMenuDTO.setApiUrl("/" +  tableInfo.getEntityPath());
            } else {
                childMenuDTO.setComponent(platformDTO.getArtifactId() + "/" + tableInfo.getEntityPath()
                        + "/index.vue");
                childMenuDTO.setApiUrl("/" + tableInfo.getEntityPath());
            }
            childMenuDTO.setPlatformId(platformDTO.getPlatformId())
                    .setMenuName(comment)
                    .setMenuType("C")
                    .setParentId(rootMenu.getMenuId())
                    .setRestful(true)
                    .setStatus("0")
                    .setVisible("0");
            RestTemplateUtils.post(childMenuDTO, Void.class);
        }
    }

    private MenuDTO createOrFind(MenuDTO input) {
        input.setUrl(gatewayUrl + Path.MENU_SEARCH + "?menuName={menuName}&platformId={platformId}");
        List<MenuDTO> list = RestTemplateUtils.get(input, new TypeReference<List<MenuDTO>>() {
        }, input.getMenuName(), input.getPlatformId());
        if(!list.isEmpty()) {
            return list.get(0);
        } else {
            input.setUrl(gatewayUrl + Path.MENU);
            return RestTemplateUtils.post(input, MenuDTO.class);
        }
    }
}
